home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / other / jikes / src / body.cpp < prev    next >
C/C++ Source or Header  |  1999-05-14  |  96KB  |  2,302 lines

  1. // $Id: body.cpp,v 1.8 1999/03/09 14:37:15 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10.  
  11. #include "config.h"
  12. #include <assert.h>
  13. #include "semantic.h"
  14. #include "control.h"
  15.  
  16. void Semantic::ProcessBlockStatements(AstBlock *block_body)
  17. {
  18.     //
  19.     // An empty block that is not a switch block can complete normally
  20.     // iff it is reachable. A nonempty block that is not a switch
  21.     // block can complete normally iff the last statement in it can
  22.     // complete normally.
  23.     //
  24.     if (block_body -> NumStatements() == 0)
  25.          block_body -> can_complete_normally = block_body -> is_reachable; 
  26.     else
  27.     {
  28.         //
  29.         // The first statement in a nonempty block that is not a
  30.         // switch block is reachable iff the block is reachable.
  31.         // Every other statement S in a nonempty block that is not a
  32.         // switch block is reachable iff the statement preceeding S
  33.         // can complete normally.
  34.         //
  35.         AstStatement *statement = (AstStatement *) block_body -> Statement(0);
  36.         statement -> is_reachable = block_body -> is_reachable;
  37.         AstStatement *first_unreachable_statement = (AstStatement *) (statement -> is_reachable ? NULL : statement);
  38.         ProcessStatement(statement);
  39.         for (int i = 1; i < block_body -> NumStatements(); i++)
  40.         {
  41.             AstStatement *previous_statement = statement;
  42.             statement = (AstStatement *) block_body -> Statement(i);
  43.             statement -> is_reachable = previous_statement -> can_complete_normally;
  44.             if (! statement -> is_reachable && (first_unreachable_statement == NULL))
  45.                 first_unreachable_statement = statement;
  46.  
  47.             ProcessStatement(statement);
  48.         }
  49.  
  50.         if (statement -> can_complete_normally)
  51.             block_body -> can_complete_normally = true;
  52.  
  53.         //
  54.         // If we have one or more unreachable statements that are contained in a
  55.         // reachable block then issue message. (If the enclosing block is not reachable
  56.         // the message will be issued later for the enclosing block.)
  57.         //
  58.         if (first_unreachable_statement && LocalBlockStack().TopBlock() -> is_reachable)
  59.         {
  60.             if (first_unreachable_statement == statement)
  61.             {
  62.                 ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
  63.                                statement -> LeftToken(),
  64.                                statement -> RightToken());
  65.             }
  66.             else
  67.             {
  68.                 ReportSemError(SemanticError::UNREACHABLE_STATEMENTS,
  69.                                first_unreachable_statement -> LeftToken(),
  70.                                statement -> RightToken());
  71.             }
  72.         }
  73.  
  74.         //
  75.         // If an enclosed block has a higher max_variable_index than the current block,
  76.         // update max_variable_index in the current_block, accordingly.
  77.         //
  78.         BlockSymbol *block = block_body -> block_symbol;
  79.         if (block -> max_variable_index < LocalBlockStack().TopMaxEnclosedVariableIndex())
  80.             block -> max_variable_index = LocalBlockStack().TopMaxEnclosedVariableIndex();
  81.     }
  82.  
  83.     return;
  84. }
  85.  
  86.  
  87. void Semantic::ProcessBlock(Ast *stmt)
  88. {
  89.     AstBlock *block_body = (AstBlock *) stmt;
  90.  
  91.     AstBlock *enclosing_block = LocalBlockStack().TopBlock();
  92.  
  93.     //
  94.     // Guess that the number of elements will not exceed the number of statements + 3. The +3 takes into account
  95.     // one label + one ForInit declaration and one extra something else.
  96.     //
  97.     int table_size = block_body -> NumStatements() + 3;
  98.     BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol(table_size);
  99.     //
  100.     // enclosing_block is not present only when we are processing the block of a static initializer
  101.     //
  102.     block -> max_variable_index = (enclosing_block ? enclosing_block -> block_symbol -> max_variable_index : 1);
  103.     LocalSymbolTable().Push(block -> Table());
  104.  
  105.     block_body -> block_symbol = block;
  106.     block_body -> nesting_level = LocalBlockStack().Size();
  107.     LocalBlockStack().Push(block_body);
  108.  
  109.     //
  110.     // Note that in constructing the Ast, the parser encloses each
  111.     // labeled statement in its own block. Therefore the declaration
  112.     // of this label will not conflict with the declaration of another
  113.     // label with the same name declared at the same nesting level.
  114.     //
  115.     // For example, the following sequence of statements is legal:
  116.     //
  117.     //     l: a = b;
  118.     //     l: b = c;
  119.     //
  120.     if (block_body -> label_token_opt)
  121.     {
  122.         NameSymbol *name_symbol = (NameSymbol *) lex_stream -> NameSymbol(block_body -> label_token_opt);
  123.         Symbol *symbol = LocalSymbolTable().FindLabelSymbol(name_symbol);
  124.         if (symbol)
  125.         {
  126.             ReportSemError(SemanticError::DUPLICATE_LABEL,
  127.                            block_body -> label_token_opt,
  128.                            block_body -> label_token_opt,
  129.                            name_symbol -> Name());
  130.         }
  131.         else
  132.         {
  133.             LabelSymbol *label = LocalSymbolTable().Top() -> InsertLabelSymbol(name_symbol);
  134.             label -> block = block_body;
  135.             label -> nesting_level = block_body -> nesting_level;
  136.         }
  137.     }
  138.  
  139.     ProcessBlockStatements(block_body);
  140.  
  141.     LocalBlockStack().Pop();
  142.     LocalSymbolTable().Pop();
  143.  
  144.     //
  145.     // Update the information for the block that immediately encloses the current block.
  146.     //
  147.     if (enclosing_block)
  148.     {
  149.         if (LocalBlockStack().TopMaxEnclosedVariableIndex() < block -> max_variable_index)
  150.             LocalBlockStack().TopMaxEnclosedVariableIndex() = block -> max_variable_index;
  151.     }
  152.  
  153.     block -> CompressSpace(); // space optimization
  154.  
  155.     return;
  156. }
  157.  
  158.  
  159. void Semantic::ProcessLocalVariableDeclarationStatement(Ast *stmt)
  160. {
  161.     AstLocalVariableDeclarationStatement *local_decl = (AstLocalVariableDeclarationStatement *) stmt;
  162.  
  163.     AstArrayType *array_type = local_decl -> type -> ArrayTypeCast();
  164.     Ast *actual_type = (array_type ? array_type -> type : local_decl -> type);
  165.  
  166.     if ((! control.option.one_one) && local_decl -> NumLocalModifiers() > 0)
  167.     {
  168.         ReportSemError(SemanticError::ONE_ONE_FEATURE,
  169.                        local_decl -> LocalModifier(0) -> LeftToken(),
  170.                        local_decl -> LocalModifier(local_decl -> NumLocalModifiers() - 1) -> RightToken());
  171.     }
  172.     AccessFlags access_flags = ProcessLocalModifiers(local_decl);
  173.  
  174.     AstPrimitiveType *primitive_type = actual_type -> PrimitiveTypeCast();
  175.     TypeSymbol *field_type = (primitive_type ? field_type = FindPrimitiveType(primitive_type) : MustFindType(actual_type));
  176.  
  177.     for (int i = 0; i < local_decl -> NumVariableDeclarators(); i++)
  178.     {
  179.         AstVariableDeclarator *variable_declarator = local_decl -> VariableDeclarator(i);
  180.         AstVariableDeclaratorId *name = variable_declarator -> variable_declarator_name;
  181.         NameSymbol *name_symbol = (NameSymbol *) lex_stream -> NameSymbol(name -> identifier_token);
  182.  
  183. //
  184. // TODO: Confirm that this new test is indeed the case. In 1.0, only the more restricted test below was necessary.
  185. //
  186. //        if (LocalSymbolTable().FindVariableSymbol(name_symbol))
  187. //        {
  188. //            ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  189. //                           name -> identifier_token,
  190. //                           name -> identifier_token,
  191. //                           name_symbol -> Name());
  192. //        }
  193. //
  194.         SemanticEnvironment *where_found;
  195.         Tuple<VariableSymbol *> variables_found(2);
  196.         SearchForVariableInEnvironment(variables_found, where_found, state_stack.Top(), name_symbol, name -> identifier_token);
  197.         VariableSymbol *symbol = (variables_found.Length() > 0 ? variables_found[0] : (VariableSymbol *) NULL);
  198.         if (symbol && symbol -> IsLocal())
  199.         {
  200.             ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  201.                            name -> identifier_token,
  202.                            name -> identifier_token,
  203.                            name_symbol -> Name());
  204.         }
  205.         else
  206.         {
  207.             symbol = LocalSymbolTable().Top() -> InsertVariableSymbol(name_symbol);
  208.             variable_declarator -> symbol = symbol;
  209.  
  210.             int num_dimensions = (array_type ? array_type -> NumBrackets() : 0) + name -> NumBrackets();
  211.             if (num_dimensions == 0)
  212.                  symbol -> SetType(field_type);
  213.             else symbol -> SetType(field_type -> GetArrayType((Semantic *) this, num_dimensions));
  214.             symbol -> SetFlags(access_flags);
  215.             symbol -> SetOwner(ThisMethod());
  216.             symbol -> declarator = variable_declarator;
  217.             BlockSymbol *block = LocalBlockStack().TopBlock() -> block_symbol;
  218.             symbol -> SetLocalVariableIndex(block -> max_variable_index++); // Assigning a local_variable_index to a variable
  219.                                                                                // also marks it complete as a side-effect.
  220.             if (symbol -> Type() == control.long_type || symbol -> Type() == control.double_type)
  221.                 block -> max_variable_index++;
  222.  
  223.             if (variable_declarator -> variable_initializer_opt)
  224.                  ProcessVariableInitializer(variable_declarator);
  225.         }
  226.     }
  227.  
  228.     //
  229.     // A local variable declaration statement can complete normally
  230.     // iff it is reachable.
  231.     //
  232.     local_decl -> can_complete_normally = local_decl -> is_reachable;
  233.  
  234.     return;
  235. }
  236.  
  237.  
  238. void Semantic::ProcessExpressionStatement(Ast *stmt)
  239. {
  240.     AstExpressionStatement *expression_statement = (AstExpressionStatement *) stmt;
  241.  
  242.     ProcessExpression(expression_statement -> expression);
  243.  
  244.     //
  245.     // An expression statement can complete normally iff it is reachable.
  246.     //
  247.     expression_statement -> can_complete_normally = expression_statement -> is_reachable;
  248.  
  249.     return;
  250. }
  251.  
  252.  
  253. void Semantic::ProcessSynchronizedStatement(Ast *stmt)
  254. {
  255.     AstSynchronizedStatement *synchronized_statement = (AstSynchronizedStatement *) stmt;
  256.  
  257.     ProcessExpression(synchronized_statement -> expression);
  258.  
  259.     synchronized_statement -> block -> is_reachable = synchronized_statement -> is_reachable;
  260.  
  261.     if (synchronized_statement -> expression -> Type() -> Primitive())
  262.     {
  263.         ReportSemError(SemanticError::TYPE_NOT_REFERENCE,
  264.                        synchronized_statement -> expression -> LeftToken(),
  265.                        synchronized_statement -> expression -> RightToken(),
  266.                        synchronized_statement -> expression -> Type() -> Name());
  267.     }
  268.  
  269.     AstBlock *enclosing_block = LocalBlockStack().TopBlock(),
  270.              *block_body = synchronized_statement -> block;
  271.  
  272.     //
  273.     // Guess that the number of elements will not exceed the number of statements + 3.
  274.     //
  275.     BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol(block_body -> NumStatements() + 3);
  276.     //
  277.     // "synchronized" blocks require two more local variable slots for synchronization,
  278.     // plus one extra variable slot if the containing method returns a value, plus an
  279.     // additional slot if the value returned is double or long.
  280.     //
  281.     block -> synchronized_variable_index = enclosing_block -> block_symbol -> max_variable_index;
  282.     block -> max_variable_index =  block -> synchronized_variable_index + 2;
  283.     if (ThisMethod() -> Type() == control.double_type || ThisMethod() -> Type() == control.long_type)
  284.          block -> max_variable_index += 2;
  285.     else if (ThisMethod() -> Type() != control.void_type)
  286.          block -> max_variable_index++;
  287.  
  288.     LocalSymbolTable().Push(block -> Table());
  289.  
  290.     block_body -> block_symbol = block;
  291.     block_body -> nesting_level = LocalBlockStack().Size();
  292.     LocalBlockStack().Push(block_body);
  293.  
  294.     ProcessBlockStatements(block_body);
  295.  
  296.     LocalBlockStack().Pop();
  297.     LocalSymbolTable().Pop();
  298.  
  299.     if (LocalBlockStack().TopMaxEnclosedVariableIndex() < block -> max_variable_index)
  300.         LocalBlockStack().TopMaxEnclosedVariableIndex() = block -> max_variable_index;
  301.  
  302.     //
  303.     // If the synchronized_statement is enclosed in a loop and it contains a reachable continue statement
  304.     // then it may have already been marked as "can complete normally";
  305.     //
  306.     synchronized_statement -> can_complete_normally = synchronized_statement -> can_complete_normally ||
  307.                                                       synchronized_statement -> block -> can_complete_normally;
  308.  
  309.     block -> CompressSpace(); // space optimization
  310.  
  311.     return;
  312. }
  313.  
  314.  
  315. void Semantic::ProcessIfStatement(Ast *stmt)
  316. {
  317.     AstIfStatement *if_statement = (AstIfStatement *) stmt;
  318.  
  319.     ProcessExpression(if_statement -> expression);
  320.  
  321.     if (if_statement -> expression -> Type() != control.no_type &&
  322.         if_statement -> expression -> Type() != control.boolean_type)
  323.     {
  324.         ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
  325.                        if_statement -> expression -> LeftToken(),
  326.                        if_statement -> expression -> RightToken(),
  327.                        if_statement -> expression -> Type() -> Name());
  328.     }
  329.  
  330.     //
  331.     // Recall that the parser ensures that the statements that appear in an if-statement
  332.     // (both the true and false statement) are enclosed in a block.
  333.     //
  334.     if_statement -> true_statement -> is_reachable = if_statement -> is_reachable;
  335.     ProcessBlock(if_statement -> true_statement);
  336.  
  337.     if (if_statement -> false_statement_opt)
  338.     {
  339.         if_statement -> false_statement_opt -> is_reachable = if_statement -> is_reachable;
  340.         ProcessBlock(if_statement -> false_statement_opt);
  341.  
  342.         //
  343.         // If the if_statement is enclosed in a loop and it contains a reachable continue statement
  344.         // then it may have already been marked as "can complete normally";
  345.         //
  346.         if_statement -> can_complete_normally = if_statement -> can_complete_normally ||
  347.                                                 if_statement -> true_statement -> can_complete_normally ||
  348.                                                 if_statement -> false_statement_opt -> can_complete_normally;
  349.     }
  350.     else if_statement -> can_complete_normally = if_statement -> is_reachable;
  351.  
  352.     return;
  353. }
  354.  
  355.  
  356. void Semantic::ProcessWhileStatement(Ast *stmt)
  357. {
  358.     AstWhileStatement *while_statement = (AstWhileStatement *) stmt;
  359.  
  360.     //
  361.     // Recall that each while statement is enclosed in a unique block by the parser
  362.     //
  363.     BreakableStatementStack().Push(LocalBlockStack().TopBlock());
  364.     ContinuableStatementStack().Push(LocalBlockStack().TopBlock());
  365.  
  366.     AstStatement *enclosed_statement = while_statement -> statement;
  367.     enclosed_statement -> is_reachable = while_statement -> is_reachable;
  368.  
  369.     ProcessExpression(while_statement -> expression);
  370.     if (while_statement -> expression -> Type() == control.boolean_type)
  371.     {
  372.         if (while_statement -> expression -> IsConstant())
  373.         {
  374.             IntLiteralValue *literal = (IntLiteralValue *) while_statement -> expression -> value;
  375.             if (! literal -> value)
  376.             {
  377.                  if (while_statement -> is_reachable)
  378.                      while_statement -> can_complete_normally = true;
  379.                  enclosed_statement -> is_reachable = false;
  380.             }
  381.         }
  382.         else if (while_statement -> is_reachable)
  383.              while_statement -> can_complete_normally = true;
  384.     }
  385.     else if (while_statement -> expression -> Type() != control.no_type)
  386.     {
  387.         ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
  388.                        while_statement -> expression -> LeftToken(),
  389.                        while_statement -> expression -> RightToken(),
  390.                        while_statement -> expression -> Type() -> Name());
  391.     }
  392.  
  393.     ProcessStatement(enclosed_statement);
  394.  
  395.     if ((! enclosed_statement -> is_reachable) && (while_statement -> is_reachable))
  396.     {
  397.         AstBlock *block_body = enclosed_statement -> BlockCast();
  398.         if (! block_body || (block_body -> NumStatements() == 0))
  399.         {
  400.             ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
  401.                            enclosed_statement -> LeftToken(),
  402.                            enclosed_statement -> RightToken());
  403.         }
  404.     }
  405.  
  406.     //
  407.     // If the while statement contained a reachable break statement,
  408.     // then the while statement can complete normally. It is marked
  409.     // here only for completeness, as marking the enclosing block is
  410.     // enough to propagate the proper information upward.
  411.     //
  412.     AstBlock *block_body = (AstBlock *) BreakableStatementStack().Top();
  413.     if (block_body -> can_complete_normally)
  414.         while_statement -> can_complete_normally = true;
  415.  
  416.     BreakableStatementStack().Pop();
  417.     ContinuableStatementStack().Pop();
  418.  
  419.     return;
  420. }
  421.  
  422.  
  423. void Semantic::ProcessForStatement(Ast *stmt)
  424. {
  425.     AstForStatement *for_statement = (AstForStatement *) stmt;
  426.  
  427.     //
  428.     // Note that in constructing the Ast, the parser encloses each
  429.     // for-statement whose for-init-statements starts with a local
  430.     // variable declaration in its own block. Therefore a redeclaration
  431.     // of another local variable with the same name in a different loop
  432.     // at the same nesting level will not cause any conflict.
  433.     //
  434.     // For example, the following sequence of statements is legal:
  435.     //
  436.     //     for (int i = 0; i < 10; i++);
  437.     //     for (int i = 10; i < 20; i++);
  438.     //
  439.     for (int i = 0; i < for_statement -> NumForInitStatements(); i++)
  440.         ProcessStatement(for_statement -> ForInitStatement(i));
  441.  
  442.     //
  443.     // Recall that each for statement is enclosed in a unique block by the parser
  444.     //
  445.     BreakableStatementStack().Push(LocalBlockStack().TopBlock());
  446.     ContinuableStatementStack().Push(LocalBlockStack().TopBlock());
  447.  
  448.     //
  449.     // Assume that if the for_statement is reachable then its
  450.     // contained statement is also reachable. If it turns out that the
  451.     // condition (end) expression is a constant FALSE expression we will
  452.     // change the assumption...
  453.     //
  454.     AstStatement *enclosed_statement = for_statement -> statement;
  455.     enclosed_statement -> is_reachable = for_statement -> is_reachable;
  456.  
  457.     if (for_statement -> end_expression_opt)
  458.     {
  459.         ProcessExpression(for_statement -> end_expression_opt);
  460.         if (for_statement -> end_expression_opt -> Type() == control.boolean_type)
  461.         {
  462.             if (for_statement -> end_expression_opt -> IsConstant())
  463.             {
  464.                 IntLiteralValue *literal = (IntLiteralValue *) for_statement -> end_expression_opt -> value;
  465.                 if (! literal -> value)
  466.                 {
  467.                      if (for_statement -> is_reachable)
  468.                          for_statement -> can_complete_normally = true;
  469.                      enclosed_statement -> is_reachable = false;
  470.                 }
  471.             }
  472.             else if (for_statement -> is_reachable)
  473.                  for_statement -> can_complete_normally = true;
  474.         }
  475.         else if (for_statement -> end_expression_opt -> Type() != control.no_type)
  476.         {
  477.             ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
  478.                            for_statement -> end_expression_opt -> LeftToken(),
  479.                            for_statement -> end_expression_opt -> RightToken(),
  480.                            for_statement -> end_expression_opt -> Type() -> Name());
  481.         }
  482.     }
  483.  
  484.     ProcessStatement(enclosed_statement);
  485.  
  486.     if ((! enclosed_statement -> is_reachable) && (for_statement -> is_reachable))
  487.     {
  488.         AstBlock *block_body = enclosed_statement -> BlockCast();
  489.         if (! block_body || (block_body -> NumStatements() == 0))
  490.         {
  491.             ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
  492.                            enclosed_statement -> LeftToken(),
  493.                            enclosed_statement -> RightToken());
  494.         }
  495.     }
  496.  
  497.     for (int j = 0; j < for_statement -> NumForUpdateStatements(); j++)
  498.         ProcessExpressionStatement(for_statement -> ForUpdateStatement(j));
  499.  
  500.     //
  501.     // If the for statement contained a reachable break statement,
  502.     // then the for statement can complete normally. It is marked
  503.     // here only for completeness, as marking the enclosing block is
  504.     // enough to propagate the proper information upward.
  505.     //
  506.     AstBlock *block_body = (AstBlock *) BreakableStatementStack().Top();
  507.     if (block_body -> can_complete_normally)
  508.         for_statement -> can_complete_normally = true;
  509.  
  510.     BreakableStatementStack().Pop();
  511.     ContinuableStatementStack().Pop();
  512.  
  513.     return;
  514. }
  515.  
  516.  
  517. void Semantic::ProcessSwitchStatement(Ast *stmt)
  518. {
  519.     AstSwitchStatement *switch_statement = (AstSwitchStatement *) stmt;
  520.  
  521.     AstBlock *enclosing_block = LocalBlockStack().TopBlock();
  522.  
  523.     //
  524.     // We estimate a size for the switch symbol table based on the number of lines in it.
  525.     //
  526.     AstBlock *block_body = switch_statement -> switch_block;
  527.     BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol();
  528.     block -> max_variable_index = enclosing_block -> block_symbol -> max_variable_index;
  529.     LocalSymbolTable().Push(block -> Table());
  530.  
  531.     block_body -> block_symbol = block;
  532.     block_body -> nesting_level = LocalBlockStack().Size();
  533.     LocalBlockStack().Push(block_body);
  534.     BreakableStatementStack().Push(block_body);
  535.  
  536.     ProcessExpression(switch_statement -> expression);
  537.     TypeSymbol *type = switch_statement -> expression -> Type();
  538.  
  539.     if (type != control.int_type  && type != control.short_type &&
  540.         type != control.char_type && type != control.byte_type  && type != control.no_type)
  541.     {
  542.         ReportSemError(SemanticError::TYPE_NOT_VALID_FOR_SWITCH,
  543.                        switch_statement -> expression -> LeftToken(),
  544.                        switch_statement -> expression -> RightToken(),
  545.                        type -> ContainingPackage() -> PackageName(),
  546.                        type -> ExternalName());
  547.     }
  548.  
  549.     switch_statement -> default_case.switch_block_statement = NULL;
  550.  
  551.     //
  552.     // A switch block is reachable iff its switch statement is reachable.
  553.     //
  554.     block_body -> is_reachable = switch_statement -> is_reachable;
  555.     for (int i = 0; i < block_body -> NumStatements(); i++)
  556.     {
  557.         AstSwitchBlockStatement *switch_block_statement = (AstSwitchBlockStatement *) block_body -> Statement(i);
  558.  
  559.         for (int j = 0; j < switch_block_statement -> NumSwitchLabels(); j++)
  560.         {
  561.             AstCaseLabel *case_label;
  562.  
  563.             if (case_label = switch_block_statement -> SwitchLabel(j) -> CaseLabelCast())
  564.             {
  565.                 ProcessExpression(case_label -> expression);
  566.  
  567.                 if (CanAssignmentConvert(type, case_label -> expression))
  568.                 {
  569.                     if (! case_label -> expression -> IsConstant())
  570.                     {
  571.                         ReportSemError(SemanticError::EXPRESSION_NOT_CONSTANT,
  572.                                        case_label -> expression -> LeftToken(),
  573.                                        case_label -> expression -> RightToken());
  574.                         case_label -> expression -> symbol = control.no_type;
  575.                     }
  576.                     else if (case_label -> expression -> Type() != control.no_type)
  577.                     {
  578.                         if (case_label -> expression -> Type() != type && type != control.no_type)
  579.                             case_label -> expression = ConvertToType(case_label -> expression, type);
  580.  
  581.                         case_label -> map_index = switch_statement -> map.Length();
  582.  
  583.                         CaseElement *case_element = compilation_unit -> ast_pool -> GenCaseElement();
  584.                         switch_statement -> map.Next() = case_element;
  585.  
  586.                         case_element -> expression = case_label -> expression;
  587.                         case_element -> switch_block_statement = switch_block_statement;
  588.                         case_element -> index = case_label -> map_index; // use this index to keep sort stable !
  589.                     }
  590.                 }
  591.                 else
  592.                 {
  593.                     ReportSemError(SemanticError::VALUE_NOT_REPRESENTABLE_IN_TYPE,
  594.                                    case_label -> expression -> LeftToken(),
  595.                                    case_label -> expression -> RightToken(),
  596.                                    type -> Name());
  597.                 }
  598.             }
  599.             else if (switch_statement -> default_case.switch_block_statement == NULL)
  600.                 switch_statement -> default_case.switch_block_statement = switch_block_statement;
  601.             else
  602.             {
  603.                 ReportSemError(SemanticError::MULTIPLE_DEFAULT_LABEL,
  604.                                ((AstDefaultLabel *) switch_block_statement -> SwitchLabel(j)) -> LeftToken(),
  605.                                ((AstDefaultLabel *) switch_block_statement -> SwitchLabel(j)) -> RightToken());
  606.             }
  607.         }
  608.  
  609.         if (switch_block_statement -> NumStatements() > 0)
  610.         {
  611.             //
  612.             // A statement in a switch block is reachable iff its
  613.             // switch statement is reachable and at least one of the
  614.             // following is true:
  615.             //
  616.             // . it bears a case or default label
  617.             // . there is a statement preceeding it in the switch block and that
  618.             // preceeding  statement can compile normally.
  619.             //
  620.             AstStatement *statement = (AstStatement *) switch_block_statement -> Statement(0);
  621.             statement -> is_reachable = switch_statement -> is_reachable;
  622.             AstStatement *first_unreachable_statement = (AstStatement *) (statement -> is_reachable ? NULL : statement);
  623.             ProcessStatement(statement);
  624.             for (int j = 1; j < switch_block_statement -> NumStatements(); j++)
  625.             {
  626.                 AstStatement *previous_statement = statement;
  627.                 statement = (AstStatement *) switch_block_statement -> Statement(j);
  628.                 if (switch_statement -> is_reachable)
  629.                 {
  630.                     statement -> is_reachable = previous_statement -> can_complete_normally;
  631.                     if ((! statement -> is_reachable) && (first_unreachable_statement == NULL))
  632.                         first_unreachable_statement = statement;
  633.                 }
  634.  
  635.                 ProcessStatement(statement);
  636.             }
  637.  
  638.             if (first_unreachable_statement)
  639.             {
  640.                 if (first_unreachable_statement == statement)
  641.                 {
  642.                     ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
  643.                                    statement -> LeftToken(),
  644.                                    statement -> RightToken());
  645.                 }
  646.                 else
  647.                 {
  648.                     ReportSemError(SemanticError::UNREACHABLE_STATEMENTS,
  649.                                    first_unreachable_statement -> LeftToken(),
  650.                                    statement -> RightToken());
  651.                 }
  652.             }
  653.         }
  654.     }
  655.  
  656.     //
  657.     // A switch statement can complete normally iff at least one of the
  658.     // following is true:
  659.     //
  660.     // . there is a reachable break statement that exits the switch
  661.     //   statement. (See ProcessBreakStatement)
  662.     // . the switch block is empty or contains only switch labels
  663.     //   //
  664.     //   // TODO: This statement seems to be erroneous. The proper statement
  665.     //   //       as implemented here is:
  666.     //   //
  667.     //   //           . the switch block is empty or contains only case labels
  668.     //   //
  669.     // . there is at least one switch label after the last switch block
  670.     //   statement group.
  671.     // . the last statement in the switch block can complete normally
  672.     //
  673.     if (block_body -> can_complete_normally)
  674.         switch_statement -> can_complete_normally = true;
  675.     else if (switch_statement -> default_case.switch_block_statement == NULL)
  676.         switch_statement -> can_complete_normally = true;
  677.     else
  678.     {
  679.         int last_index = block_body -> NumStatements() - 1;
  680.         AstSwitchBlockStatement *last_switch_block_statement =
  681.                                  (AstSwitchBlockStatement *) block_body -> Statement(last_index);
  682.         //
  683.         // Last switch block statement contains only switch labels.
  684.         //
  685.         if (last_switch_block_statement -> NumStatements() == 0)
  686.             switch_statement -> can_complete_normally = true;
  687.         else 
  688.         {
  689.             //
  690.             // Last switch block statement contains only switch statements
  691.             //
  692.             AstStatement *last_statement =
  693.                   (AstStatement *) last_switch_block_statement -> Statement(last_switch_block_statement -> NumStatements() - 1);
  694.             if (last_statement -> can_complete_normally)
  695.                 switch_statement -> can_complete_normally = true;
  696.         }
  697.     }
  698.  
  699.     switch_statement -> SortCases();
  700.     for (int k = 1; k < switch_statement -> map.Length(); k++)
  701.     {
  702.         if (switch_statement -> map[k] -> Value() == switch_statement -> map[k - 1] -> Value())
  703.         {
  704.             wchar_t info[12],
  705.                     *str = &info[11];
  706.             int n = switch_statement -> map[k] -> Value();
  707.             bool negative = (n < 0);
  708.             if (negative)
  709.                 n = -n;
  710.             *str = U_NULL;
  711.             do
  712.             {
  713.                 *--str = (U_0 + n % 10);
  714.                 n /= 10;
  715.             } while (n != 0);
  716.             if (negative)
  717.                 *--str = '-';
  718.  
  719.             ReportSemError(SemanticError::DUPLICATE_CASE_VALUE,
  720.                            switch_statement -> map[k] -> expression -> LeftToken(),
  721.                            switch_statement -> map[k] -> expression -> RightToken(),
  722.                            str);
  723.         }
  724.     }
  725.  
  726.     //
  727.     // If an enclosed block has a higher max_variable_index than the current block,
  728.     // update max_variable_index in the current_block, accordingly.
  729.     // Also, update the information for the block that immediately encloses the current block.
  730.     //
  731.     if (block -> max_variable_index < LocalBlockStack().TopMaxEnclosedVariableIndex())
  732.         block -> max_variable_index = LocalBlockStack().TopMaxEnclosedVariableIndex();
  733.  
  734.     BreakableStatementStack().Pop();
  735.     LocalBlockStack().Pop();
  736.     LocalSymbolTable().Pop();
  737.  
  738.     if (enclosing_block)
  739.     {
  740.         if (LocalBlockStack().TopMaxEnclosedVariableIndex() < block -> max_variable_index)
  741.             LocalBlockStack().TopMaxEnclosedVariableIndex() = block -> max_variable_index;
  742.     }
  743.  
  744.     block -> CompressSpace(); // space optimization
  745.  
  746.     return;
  747. }
  748.  
  749.  
  750. void Semantic::ProcessDoStatement(Ast *stmt)
  751. {
  752.     AstDoStatement *do_statement = (AstDoStatement *) stmt;
  753.  
  754.     //
  755.     // Recall that each Do statement is enclosed in a unique block by the parser
  756.     //
  757.     BreakableStatementStack().Push(LocalBlockStack().TopBlock());
  758.     ContinuableStatementStack().Push(LocalBlockStack().TopBlock());
  759.  
  760.     AstStatement *enclosed_statement = do_statement -> statement;
  761.     enclosed_statement -> is_reachable = do_statement -> is_reachable;
  762.  
  763.     ProcessStatement(enclosed_statement);
  764.  
  765.     ProcessExpression(do_statement -> expression);
  766.  
  767.     IntLiteralValue *literal = NULL;
  768.     if (do_statement -> expression -> Type() == control.boolean_type)
  769.     {
  770.         if (do_statement -> expression -> IsConstant())
  771.             literal = (IntLiteralValue *) do_statement -> expression -> value;
  772.     }
  773.     else if (do_statement -> expression -> Type() != control.no_type)
  774.     {
  775.         ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
  776.                        do_statement -> expression -> LeftToken(),
  777.                        do_statement -> expression -> RightToken(),
  778.                        do_statement -> expression -> Type() -> Name());
  779.     }
  780.  
  781.     //
  782.     // A do statement can complete normally, iff at least one of the following is true:
  783.     //     1. The contained statement can complete normally and the condition expression
  784.     //        is not a constant expression with the value true
  785.     //     2. There is a reachable break statement that exits the do statement
  786.     //        (This condition is true is the block that immediately encloses this do statement
  787.     //         can complete normally. See ProcessBreakStatement)
  788.     //
  789.     AstBlock *block_body = (AstBlock *) BreakableStatementStack().Top();
  790.     do_statement -> can_complete_normally = (enclosed_statement -> can_complete_normally && ((! literal) || literal -> value == 0)) ||
  791.                                             block_body -> can_complete_normally; 
  792.  
  793.     BreakableStatementStack().Pop();
  794.     ContinuableStatementStack().Pop();
  795.  
  796.     return;
  797. }
  798.  
  799.  
  800. void Semantic::ProcessBreakStatement(Ast *stmt)
  801. {
  802.     AstBreakStatement *break_statement = (AstBreakStatement *) stmt;
  803.  
  804.     //
  805.     // Recall that it is possible to break out of any labeled statement even if it is not a
  806.     // do, for, while or switch statement.
  807.     //
  808.     if (break_statement -> identifier_token_opt)
  809.     {
  810.         NameSymbol *name_symbol = (NameSymbol *) lex_stream -> NameSymbol(break_statement -> identifier_token_opt);
  811.         LabelSymbol *label_symbol = LocalSymbolTable().FindLabelSymbol(name_symbol);
  812.  
  813.         if (label_symbol)
  814.         {
  815.             break_statement -> nesting_level = label_symbol -> nesting_level;
  816.             AstBlock *block_body = label_symbol -> block;
  817.             //
  818.             // A labeled statement can complete normally if there is a
  819.             // reachable break statement that exits the labeled statement.
  820.             //
  821.             if (block_body && break_statement -> is_reachable)
  822.                 block_body -> can_complete_normally = true;
  823.         }
  824.         else
  825.         {
  826.             AstBlock *block_body = (AstBlock *) LocalBlockStack().TopBlock();
  827.             break_statement -> nesting_level = block_body -> nesting_level;
  828.             ReportSemError(SemanticError::UNDECLARED_LABEL,
  829.                            break_statement -> identifier_token_opt,
  830.                            break_statement -> identifier_token_opt,
  831.                            lex_stream -> Name(break_statement -> identifier_token_opt));
  832.         }
  833.     }
  834.     else
  835.     {
  836.         AstBlock *block_body = (AstBlock *) (BreakableStatementStack().Size() > 0 ? BreakableStatementStack().Top()
  837.                                                                                   : LocalBlockStack().TopBlock());
  838.         break_statement -> nesting_level = block_body -> nesting_level;
  839.         if (BreakableStatementStack().Size() > 0)
  840.         {
  841.             if (break_statement -> is_reachable)
  842.                 block_body -> can_complete_normally = true;
  843.         }
  844.         else ReportSemError(SemanticError::MISPLACED_BREAK_STATEMENT,
  845.                             break_statement -> LeftToken(),
  846.                             break_statement -> RightToken());
  847.     }
  848.  
  849.     return;
  850. }
  851.  
  852.  
  853. void Semantic::ProcessContinueStatement(Ast *stmt)
  854. {
  855.     AstContinueStatement *continue_statement = (AstContinueStatement *) stmt;
  856.  
  857.     //
  858.     // The loop statement that is to be continued.
  859.     //
  860.     Ast *loop_statement = NULL;
  861.  
  862.     if (ContinuableStatementStack().Size() <= 0)
  863.     {
  864.         ReportSemError(SemanticError::MISPLACED_CONTINUE_STATEMENT,
  865.                        continue_statement -> LeftToken(),
  866.                        continue_statement -> RightToken());
  867.     }
  868.     else if (continue_statement -> identifier_token_opt)
  869.     {
  870.         NameSymbol *name_symbol = (NameSymbol *) lex_stream -> NameSymbol(continue_statement -> identifier_token_opt);
  871.         LabelSymbol *label_symbol = LocalSymbolTable().FindLabelSymbol(name_symbol);
  872.  
  873.         if (label_symbol)
  874.         {
  875.             continue_statement -> nesting_level = label_symbol -> nesting_level;
  876. assert(label_symbol -> block -> NumStatements() > 0);
  877.             loop_statement = label_symbol -> block -> Statement(0);
  878.         }
  879.         else
  880.         {
  881.             AstBlock *block_body = (AstBlock *) LocalBlockStack().TopBlock();
  882.             continue_statement -> nesting_level = block_body -> nesting_level;
  883.             ReportSemError(SemanticError::UNDECLARED_LABEL,
  884.                            continue_statement -> identifier_token_opt,
  885.                            continue_statement -> identifier_token_opt,
  886.                            lex_stream -> Name(continue_statement -> identifier_token_opt));
  887.         }
  888.     }
  889.     else
  890.     {
  891.         AstBlock *block_body = (AstBlock *) ContinuableStatementStack().Top();
  892.         loop_statement = block_body -> Statement(0);
  893.         continue_statement -> nesting_level = block_body -> nesting_level;
  894.     }
  895.  
  896.     //
  897.     // If this is a valid continue statement, it is associated with a loop statement.
  898.     // Since the loop can be continued, its enclosed statement "can complete normally".
  899.     //
  900.     if (loop_statement)
  901.     {
  902.         AstDoStatement *do_statement = loop_statement -> DoStatementCast();
  903.         AstForStatement *for_statement = loop_statement -> ForStatementCast();
  904.         AstWhileStatement *while_statement = loop_statement -> WhileStatementCast();
  905.  
  906.         AstStatement *enclosed_statement = (do_statement ? do_statement -> statement
  907.                                                          : (for_statement ? for_statement -> statement
  908.                                                                           : (while_statement ? while_statement -> statement
  909.                                                                                              : NULL)));
  910.         if (enclosed_statement)
  911.             enclosed_statement -> can_complete_normally = true;
  912.         else
  913.         {
  914. assert(continue_statement -> identifier_token_opt);
  915.             ReportSemError(SemanticError::INVALID_CONTINUE_TARGET,
  916.                            continue_statement -> LeftToken(),
  917.                            continue_statement -> RightToken(),
  918.                            lex_stream -> Name(continue_statement -> identifier_token_opt));
  919.         }
  920.     }
  921.  
  922.     return;
  923. }
  924.  
  925.  
  926. void Semantic::ProcessReturnStatement(Ast *stmt)
  927. {
  928.     AstReturnStatement *return_statement = (AstReturnStatement *) stmt;
  929.  
  930.     MethodSymbol *this_method = ThisMethod();
  931.  
  932.     if (this_method -> name_symbol == control.clinit_name_symbol || this_method -> name_symbol == control.block_init_name_symbol)
  933.     {
  934.         ReportSemError(SemanticError::RETURN_STATEMENT_IN_INITIALIZER,
  935.                        return_statement -> LeftToken(),
  936.                        return_statement -> RightToken());
  937.     }
  938.     else if (return_statement -> expression_opt)
  939.     {
  940.         ProcessExpression(return_statement -> expression_opt);
  941.  
  942.         if (this_method -> Type() == control.void_type)
  943.         {
  944.             ReportSemError(SemanticError::MISPLACED_RETURN_WITH_EXPRESSION,
  945.                            return_statement -> LeftToken(),
  946.                            return_statement -> RightToken());
  947.         }
  948.         else if (return_statement -> expression_opt -> Type() != control.no_type)
  949.         {
  950.             if (! CanAssignmentConvert(this_method -> Type(), return_statement -> expression_opt))
  951.             {
  952.                 ReportSemError(SemanticError::MISMATCHED_RETURN_AND_METHOD_TYPE,
  953.                                return_statement -> expression_opt -> LeftToken(),
  954.                                return_statement -> expression_opt -> RightToken(),
  955.                                return_statement -> expression_opt -> Type() -> ContainingPackage() -> PackageName(),
  956.                                return_statement -> expression_opt -> Type() -> ExternalName(),
  957.                                this_method -> Type() -> ContainingPackage() -> PackageName(),
  958.                                this_method -> Type() -> ExternalName());
  959.             }
  960.         }
  961.     }
  962.     else if (this_method -> Type() != control.void_type)
  963.     {
  964.         ReportSemError(SemanticError::MISPLACED_RETURN_WITH_NO_EXPRESSION,
  965.                        return_statement -> LeftToken(),
  966.                        return_statement -> RightToken());
  967.     }
  968.  
  969.     return;
  970. }
  971.  
  972.  
  973. bool Semantic::CatchableException(TypeSymbol *exception)
  974. {
  975.     //
  976.     // An unchecked exception or an error is ok !!
  977.     //
  978.     if (! CheckedException(exception) || exception == control.no_type)
  979.         return true;
  980.  
  981.     //
  982.     // Firstly, check the stack of try statements to see if the exception in question is catchable.
  983.     //
  984.     for (int i = TryStatementStack().Size() - 1; i >= 0; i--)
  985.     {
  986.         AstTryStatement *try_statement = (AstTryStatement *) TryStatementStack()[i];
  987.  
  988.         //
  989.         // If a try statement contains a finally clause that can complete abruptly
  990.         // then any exception that can reach it is assumed to be catchable.
  991.         // See Spec 11.3.
  992.         //
  993.         if (try_statement -> finally_clause_opt && (! try_statement -> finally_clause_opt -> block -> can_complete_normally))
  994.             return true;
  995.  
  996.         //
  997.         // Check each catch clause in turn.
  998.         //
  999.         for (int k = 0; k < try_statement -> NumCatchClauses(); k++)
  1000.         {
  1001.             AstCatchClause *clause = try_statement -> CatchClause(k);
  1002.             VariableSymbol *symbol = clause -> parameter_symbol;
  1003.             if (CanAssignmentConvertReference(symbol -> Type(), exception))
  1004.                 return true;
  1005.         }
  1006.     }
  1007.  
  1008.     //
  1009.     // If we are processing the initialization expression of a field,
  1010.     // ThisMethod() is not defined.
  1011.     //
  1012.     MethodSymbol *this_method = ThisMethod();
  1013.     if (this_method)
  1014.     {
  1015.         for (int l = this_method -> NumThrows() - 1; l >= 0; l--)
  1016.         {
  1017.             if (CanAssignmentConvertReference(this_method -> Throws(l), exception))
  1018.                 return true;
  1019.         }
  1020.  
  1021.         if (this_method -> NumInitializerConstructors() > 0)
  1022.         {
  1023.             int j;
  1024.             for (j = this_method -> NumInitializerConstructors() - 1; j >= 0; j--)
  1025.             {
  1026.                 MethodSymbol *method = this_method -> InitializerConstructor(j);
  1027.                 int k;
  1028.                 for (k = method -> NumThrows() - 1; k >= 0; k--)
  1029.                 {
  1030.                     if (CanAssignmentConvertReference(method -> Throws(k), exception))
  1031.                         break;
  1032.                 }
  1033.                 if (k < 0) // no hit was found in method.
  1034.                     return false;
  1035.             }
  1036.             if (j < 0) // all the relevant constructors can catch the exception
  1037.                 return true;
  1038.         }
  1039.     }
  1040.  
  1041.     return false;
  1042. }
  1043.  
  1044.  
  1045. void Semantic::ProcessThrowStatement(Ast *stmt)
  1046. {
  1047.     AstThrowStatement *throw_statement = (AstThrowStatement *) stmt;
  1048.  
  1049.     ProcessExpression(throw_statement -> expression);
  1050.     TypeSymbol *type = throw_statement -> expression -> Type();
  1051.  
  1052.     if (type != control.no_type && (! CanAssignmentConvertReference(control.Throwable(), type)))
  1053.     {
  1054.         ReportSemError(SemanticError::EXPRESSION_NOT_THROWABLE,
  1055.                        throw_statement -> LeftToken(),
  1056.                        throw_statement -> RightToken());
  1057.     }
  1058.  
  1059.     SymbolSet *exception_set = TryExceptionTableStack().Top();
  1060.     if (exception_set)
  1061.         exception_set -> AddElement(type);
  1062.  
  1063.     if (! CatchableException(type))
  1064.     {
  1065.         MethodSymbol *this_method = ThisMethod();
  1066.         MethodSymbol *method = (this_method && this_method -> Identity() != control.clinit_name_symbol
  1067.                                             && this_method -> Identity() != control.block_init_name_symbol
  1068.                                                             ? this_method
  1069.                                                             : (MethodSymbol *) NULL);
  1070.  
  1071.         if (TryStatementStack().Size() > 0)
  1072.             ReportSemError(SemanticError::BAD_THROWABLE_EXPRESSION_IN_TRY,
  1073.                            throw_statement -> LeftToken(),
  1074.                            throw_statement -> RightToken(),
  1075.                            type -> ContainingPackage() -> PackageName(),
  1076.                            type -> ExternalName(),
  1077.                            (method ? method -> Header() : StringConstant::US_EMPTY));
  1078.         else if (method)
  1079.              ReportSemError(SemanticError::BAD_THROWABLE_EXPRESSION_IN_METHOD,
  1080.                             throw_statement -> LeftToken(),
  1081.                             throw_statement -> RightToken(),
  1082.                             type -> ContainingPackage() -> PackageName(),
  1083.                             type -> ExternalName(),
  1084.                             method -> Header());
  1085.         else ReportSemError(SemanticError::BAD_THROWABLE_EXPRESSION,
  1086.                             throw_statement -> LeftToken(),
  1087.                             throw_statement -> RightToken(),
  1088.                             type -> ContainingPackage() -> PackageName(),
  1089.                             type -> ExternalName());
  1090.     }
  1091.  
  1092.     return;
  1093. }
  1094.  
  1095.  
  1096. void Semantic::ProcessTryStatement(Ast *stmt)
  1097. {
  1098.     AstTryStatement *try_statement = (AstTryStatement *) stmt;
  1099.  
  1100.     //
  1101.     // A try_statement containing a finally clause requires some extra local
  1102.     // variables in its immediately enclosing block. If it is enclosed in a method
  1103.     // that returns void then 2 extra elements are needed. If the method 
  1104.     // returns a long or a double value, two additional elements are needed.
  1105.     // Otherwise, one additional element is needed.
  1106.     // If this try_statement is the first try_statement with a finally clause
  1107.     // that was encountered in the immediately enclosing block, we allocate
  1108.     // two extra slots for the special local variables.
  1109.     //
  1110.     AstBlock *enclosing_block = LocalBlockStack().TopBlock();
  1111.     if (try_statement -> finally_clause_opt)
  1112.     {
  1113.         BlockSymbol *block = enclosing_block -> block_symbol;
  1114.         if (block -> try_variable_index == 0) // first try_statement encountered in enclosing block?
  1115.         {
  1116.             block -> try_variable_index = block -> max_variable_index;
  1117.             block -> max_variable_index += 2;
  1118.             if (ThisMethod() -> Type() != control.void_type)
  1119.             {
  1120.                  if (control.IsDoubleWordType(ThisMethod() -> Type()))
  1121.                       block -> max_variable_index += 2;
  1122.                  else block -> max_variable_index += 1;
  1123.             }
  1124.         }
  1125.  
  1126.         //
  1127.         // A finally block is processed in the environment of its immediate enclosing block.
  1128.         // (as opposed to the environment of its associated try block).
  1129.         //
  1130.         // Note that the finally block must be processed prior to the other
  1131.         // blocks in the try statement, because the computation of whether or not
  1132.         // an exception is catchable in a try statement depends on the termination
  1133.         // status of the associated finally block. See CatchableException function.
  1134.         //
  1135.         AstBlock *block_body = try_statement -> finally_clause_opt -> block;
  1136.         block_body -> is_reachable = try_statement -> is_reachable;
  1137.         ProcessBlock(block_body);
  1138.     }
  1139.  
  1140.     //
  1141.     // Note that the catch clauses are processed first - prior to processing
  1142.     // the main block - so that we can have their parameters available when we
  1143.     // are processing the main block, in case that block contains a throw
  1144.     // statement. See ProcessThrowStatement for more information.
  1145.     //
  1146.     // Also, recall that the body of the catch blocks must not be
  1147.     // processed within the environment of the associated try whose
  1148.     // exceptions they are supposed to catch but within the immediate enclosing
  1149.     // block (which may itself be a try block).
  1150.     //
  1151.     for (int i = 0; i < try_statement -> NumCatchClauses(); i++)
  1152.     {
  1153.         AstCatchClause *clause = try_statement -> CatchClause(i);
  1154.         AstFormalParameter *parameter = clause -> formal_parameter;
  1155.  
  1156.         TypeSymbol *parm_type;
  1157.  
  1158.         if (parameter -> type -> PrimitiveTypeCast())
  1159.         {
  1160.             ReportSemError(SemanticError::CATCH_PRIMITIVE_TYPE,
  1161.                            parameter -> LeftToken(),
  1162.                            parameter -> RightToken());
  1163.             parm_type = control.Error();
  1164.         }
  1165.         else if (parameter -> type -> ArrayTypeCast())
  1166.         {
  1167.             ReportSemError(SemanticError::CATCH_ARRAY_TYPE,
  1168.                            parameter -> LeftToken(),
  1169.                            parameter -> RightToken());
  1170.             parm_type = control.Error();
  1171.         }
  1172.         else parm_type = MustFindType(parameter -> type);
  1173.  
  1174.         if (! parm_type -> IsSubclass(control.Throwable()))
  1175.         {
  1176.             ReportSemError(SemanticError::TYPE_NOT_THROWABLE,
  1177.                            parameter -> LeftToken(),
  1178.                            parameter -> RightToken(),
  1179.                            parm_type -> ContainingPackage() -> PackageName(),
  1180.                            parm_type -> ExternalName());
  1181.         }
  1182.  
  1183.         AstVariableDeclaratorId *name = parameter -> variable_declarator_name;
  1184.         NameSymbol *name_symbol = (NameSymbol *) lex_stream -> NameSymbol(name -> identifier_token);
  1185.         if (LocalSymbolTable().FindVariableSymbol(name_symbol))
  1186.         {
  1187.             ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  1188.                            name -> identifier_token,
  1189.                            name -> identifier_token,
  1190.                            name_symbol -> Name());
  1191.         }
  1192.  
  1193.         AstBlock *block_body = clause -> block;
  1194.         //
  1195.         // Guess that the number of elements in the table will not exceed the number of statements + the clause parameter.
  1196.         //
  1197.         BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol(block_body -> NumStatements() + 1);
  1198.         block -> max_variable_index = enclosing_block -> block_symbol -> max_variable_index;
  1199.         LocalSymbolTable().Push(block -> Table());
  1200.  
  1201.         if ((! control.option.one_one) && parameter -> NumParameterModifiers() > 0)
  1202.         {
  1203.             ReportSemError(SemanticError::ONE_ONE_FEATURE,
  1204.                            parameter -> ParameterModifier(0) -> LeftToken(),
  1205.                            parameter -> ParameterModifier(0) -> RightToken());
  1206.         }
  1207.         AccessFlags access_flags = ProcessFormalModifiers(parameter);
  1208.  
  1209.         VariableSymbol *symbol = LocalSymbolTable().Top() -> InsertVariableSymbol(name_symbol);
  1210.         symbol -> SetFlags(access_flags);
  1211.         symbol -> SetType(parm_type);
  1212.         symbol -> SetOwner(ThisMethod());
  1213.         symbol -> SetLocalVariableIndex(block -> max_variable_index++);
  1214.         symbol -> declarator = parameter -> variable_declarator_name;
  1215.  
  1216.         clause -> parameter_symbol = symbol;
  1217.  
  1218.         //
  1219.         // Note that for the purpose of semantic checking we assume that
  1220.         // the body of the catch block is reachable. Whether or not the catch
  1221.         // statement can be executed at all is checked later.
  1222.         //
  1223.         block_body -> is_reachable = true;
  1224.  
  1225.         block_body -> block_symbol = block;
  1226.         block_body -> nesting_level = LocalBlockStack().Size();
  1227.         LocalBlockStack().Push(block_body);
  1228.  
  1229.         ProcessBlockStatements(block_body);
  1230.  
  1231.         LocalBlockStack().Pop();
  1232.         LocalSymbolTable().Pop();
  1233.  
  1234.         //
  1235.         // Update the information for the block that immediately encloses the current block.
  1236.         //
  1237.         if (LocalBlockStack().TopMaxEnclosedVariableIndex() < block -> max_variable_index)
  1238.             LocalBlockStack().TopMaxEnclosedVariableIndex() = block -> max_variable_index;
  1239.  
  1240.         //
  1241.         // If a catch clause block can complete normally, we assume
  1242.         // that the try statement can complete normally. This may
  1243.         // prove to be false later if we find out that the finally
  1244.         // clause cannot complete normally...
  1245.         //
  1246.         if (block_body -> can_complete_normally)
  1247.             try_statement -> can_complete_normally = true;
  1248.  
  1249.         block -> CompressSpace(); // space optimization
  1250.     }
  1251.  
  1252.     //
  1253.     //
  1254.     //
  1255.     TryStatementStack().Push(try_statement);
  1256.     SymbolSet *exception_set = new SymbolSet;
  1257.     TryExceptionTableStack().Push(exception_set);
  1258.  
  1259.     try_statement -> block -> is_reachable = try_statement -> is_reachable;
  1260.     ProcessBlock(try_statement -> block);
  1261.     if (try_statement -> block -> can_complete_normally)
  1262.         try_statement -> can_complete_normally = true;
  1263.  
  1264.     //
  1265.     // A catch block is reachable iff both of the following are true:
  1266.     //
  1267.     //     . Some expression or throw statement in the try block is reachable
  1268.     //       and can throw an exception that is assignable to the parameter
  1269.     //       of the catch clause C.
  1270.     //
  1271.     //     . There is no earlier catch block A in the try statement such that the
  1272.     //       type of C's parameter is the same as or a subclass of the type of A's
  1273.     //       parameter.
  1274.     //
  1275.     for (int l = 0; l < try_statement -> NumCatchClauses(); l++)
  1276.     {
  1277.         AstCatchClause *clause = try_statement -> CatchClause(l);
  1278.         VariableSymbol *symbol = clause -> parameter_symbol;
  1279.         if (CheckedException(symbol -> Type()))
  1280.         {
  1281.             TypeSymbol *exception;
  1282.             for (exception = (TypeSymbol *) exception_set -> FirstElement();
  1283.                  exception;
  1284.                  exception = (TypeSymbol *) exception_set -> NextElement())
  1285.             {
  1286.                 if (CanAssignmentConvertReference(symbol -> Type(), exception) ||
  1287.                     CanAssignmentConvertReference(exception, symbol -> Type()))
  1288.                     break;
  1289.             }
  1290.  
  1291.             AstCatchClause *previous_clause;
  1292.             int k;
  1293.             for (k = 0; k < l; k++)
  1294.             {
  1295.                 previous_clause = try_statement -> CatchClause(k);
  1296.                 if (symbol -> Type() -> IsSubclass(previous_clause -> parameter_symbol -> Type()))
  1297.                     break;
  1298.             }
  1299.  
  1300.             if (! exception) // no assignable exception was found
  1301.             {
  1302.                  ReportSemError(SemanticError::UNREACHABLE_CATCH_CLAUSE,
  1303.                                 clause -> formal_parameter -> LeftToken(),
  1304.                                 clause -> formal_parameter -> RightToken(),
  1305.                                 symbol -> Type() -> ContainingPackage() -> PackageName(),
  1306.                                 symbol -> Type() -> ExternalName());
  1307.             }
  1308.             else if (k < l)
  1309.             {
  1310.                  FileLocation loc(lex_stream, previous_clause -> formal_parameter -> variable_declarator_name -> identifier_token);
  1311.                  ReportSemError(SemanticError::BLOCKED_CATCH_CLAUSE,
  1312.                                 clause -> formal_parameter -> LeftToken(),
  1313.                                 clause -> formal_parameter -> RightToken(),
  1314.                                 symbol -> Type() -> ContainingPackage() -> PackageName(),
  1315.                                 symbol -> Type() -> ExternalName(),
  1316.                                 loc.location);
  1317.             }
  1318.             else clause -> block -> is_reachable = true;
  1319.         }
  1320.     }
  1321.  
  1322.     TryStatementStack().Pop();
  1323.     TryExceptionTableStack().Pop();
  1324.     if (TryExceptionTableStack().Top())
  1325.         TryExceptionTableStack().Top() -> Union(*exception_set);
  1326.     delete exception_set;
  1327.  
  1328.     //
  1329.     // A try statement cannot complete normally if it contains a finally
  1330.     // clause that cannot complete normally.
  1331.     //
  1332.     if (try_statement -> finally_clause_opt && (! try_statement -> finally_clause_opt -> block -> can_complete_normally))
  1333.         try_statement -> can_complete_normally = false;
  1334.  
  1335.     return;
  1336. }
  1337.  
  1338.  
  1339. void Semantic::ProcessEmptyStatement(Ast *stmt)
  1340. {
  1341.     AstEmptyStatement *empty_statement = (AstEmptyStatement *) stmt;
  1342.  
  1343.     //
  1344.     // An empty statement can complete normally iff it is reachable.
  1345.     //
  1346.     empty_statement -> can_complete_normally = empty_statement -> is_reachable;
  1347.  
  1348.     return;
  1349. }
  1350.  
  1351.  
  1352. TypeSymbol *Semantic::GetLocalType(AstClassDeclaration *class_declaration)
  1353. {
  1354.     NameSymbol *name_symbol = (NameSymbol *) lex_stream -> NameSymbol(class_declaration -> identifier_token);
  1355.     TypeSymbol *type = LocalSymbolTable().Top() -> InsertNestedTypeSymbol(name_symbol);
  1356.  
  1357.     TypeSymbol *outermost_type = ThisType() -> outermost_type;
  1358.     if (! outermost_type -> local)
  1359.         outermost_type -> local = new SymbolSet;
  1360.  
  1361.     int num = outermost_type -> local -> NameCount(name_symbol) + 1;
  1362.     wchar_t str[11],
  1363.             *p = &str[10];
  1364.     *p = U_NULL;
  1365.     do
  1366.     {
  1367.         p--;
  1368.         *p = U_0 + (num % 10);
  1369.         num /= 10;
  1370.     } while (num > 0);
  1371.  
  1372.     int length = wcslen(p) + outermost_type -> NameLength() + 1 + name_symbol -> NameLength() + 1; // +1 for $,... +1 for $
  1373.     wchar_t *external_name = new wchar_t[length + 1]; // +1 for '\0';
  1374.     wcscpy(external_name, outermost_type -> Name());
  1375.     wcscat(external_name, StringConstant::US__DS_);
  1376.     wcscat(external_name, p);
  1377.     wcscat(external_name, StringConstant::US__DS_);
  1378.     wcscat(external_name, name_symbol -> Name());
  1379.  
  1380.     type -> SetACC_PRIVATE();
  1381.     type -> outermost_type = outermost_type;
  1382.     type -> SetExternalIdentity(control.FindOrInsertName(external_name, length));
  1383.     outermost_type -> local -> AddElement(type);
  1384.  
  1385.     delete [] external_name;
  1386.  
  1387.     return type;
  1388. }
  1389.  
  1390.  
  1391. void Semantic::ProcessClassDeclaration(Ast *stmt)
  1392. {
  1393.     AstClassDeclaration *class_declaration = (AstClassDeclaration *) stmt;
  1394.     AstClassBody *class_body = class_declaration -> class_body;
  1395.  
  1396.     class_declaration -> MarkLocal(); // identify class as "statement" and assert that it is "reachable" and "can_complete_normally"
  1397.     if (! control.option.one_one)
  1398.     {
  1399.         ReportSemError(SemanticError::ONE_ONE_FEATURE,
  1400.                        class_declaration -> LeftToken(),
  1401.                        class_declaration -> RightToken());
  1402.     }
  1403.  
  1404.     CheckNestedTypeDuplication(state_stack.Top(), class_declaration -> identifier_token);
  1405.  
  1406.     NameSymbol *name_symbol = (NameSymbol *) lex_stream -> NameSymbol(class_declaration -> identifier_token);
  1407.  
  1408.     TypeSymbol *inner_type = GetLocalType(class_declaration);
  1409.     inner_type -> outermost_type = ThisType() -> outermost_type;
  1410.     inner_type -> supertypes_closure = new SymbolSet;
  1411.     inner_type -> subtypes_closure = new SymbolSet;
  1412.     inner_type -> subtypes = new SymbolSet;
  1413.     inner_type -> semantic_environment = new SemanticEnvironment((Semantic *) this,
  1414.                                                                  inner_type,
  1415.                                                                  state_stack.Top());
  1416.     inner_type -> declaration = class_declaration;
  1417.     inner_type -> file_symbol = source_file_symbol;
  1418.     inner_type -> SetFlags(ProcessLocalClassModifiers(class_declaration));
  1419.     inner_type -> SetOwner(ThisMethod());
  1420.     //
  1421.     // Add 3 extra elements for padding. May need a default constructor and other support elements.
  1422.     //
  1423.     inner_type -> SetSymbolTable(class_body -> NumClassBodyDeclarations() + 3);
  1424.     inner_type -> SetLocation();
  1425.     inner_type -> SetSignature(control);
  1426.  
  1427.     if (StaticRegion())
  1428.          inner_type -> SetACC_STATIC();
  1429.     else inner_type -> InsertThis(0);
  1430.  
  1431.     class_declaration -> semantic_environment = inner_type -> semantic_environment; // save for processing bodies later.
  1432.  
  1433.     CheckClassMembers(inner_type, class_body);
  1434.  
  1435.     ProcessTypeHeaders(class_declaration);
  1436.     ProcessMembers(class_declaration -> semantic_environment, class_body);
  1437.     CompleteSymbolTable(class_declaration -> semantic_environment, class_declaration -> identifier_token, class_body);
  1438.     ProcessExecutableBodies(class_declaration -> semantic_environment, class_body);
  1439.  
  1440.     UpdateLocalConstructors(inner_type);
  1441.  
  1442.     return;
  1443. }
  1444.  
  1445.  
  1446. void Semantic::ProcessThisCall(AstThisCall *this_call)
  1447. {
  1448.     TypeSymbol *this_type = ThisType(),
  1449.                *containing_type = this_type -> ContainingType();
  1450.  
  1451.     ExplicitConstructorInvocation() = this_call; // signal that we are about to process an explicit constructor invocation
  1452.  
  1453.     if (this_call -> base_opt)
  1454.     {
  1455.         if (! control.option.one_one)
  1456.         {
  1457.             ReportSemError(SemanticError::ONE_ONE_FEATURE,
  1458.                            this_call -> base_opt -> LeftToken(),
  1459.                            this_call -> dot_token_opt);
  1460.         }
  1461.  
  1462.         ProcessExpression(this_call -> base_opt);
  1463.  
  1464.         TypeSymbol *expr_type = this_call -> base_opt -> Type();
  1465.         if (expr_type != control.no_type)
  1466.         {
  1467.             if (! containing_type)
  1468.             {
  1469.                 ReportSemError(SemanticError::TYPE_NOT_INNER_CLASS,
  1470.                                this_call -> base_opt -> LeftToken(),
  1471.                                this_call -> base_opt -> RightToken(),
  1472.                                this_type -> ContainingPackage() -> PackageName(),
  1473.                                this_type -> ExternalName(),
  1474.                                expr_type -> ContainingPackage() -> PackageName(),
  1475.                                expr_type -> ExternalName());
  1476.                 this_call -> base_opt -> symbol = control.no_type;
  1477.             }
  1478.             //
  1479.             // 1.2 change. In 1.1, we used to allow access to any subclass of type. Now, there must
  1480.             // be a perfect match.
  1481.             //
  1482.             // else if (! expr_type -> IsSubclass(containing_type))
  1483.             //
  1484.             else if (expr_type != containing_type)
  1485.             {
  1486.                 ReportSemError(SemanticError::INVALID_ENCLOSING_INSTANCE,
  1487.                                this_call -> base_opt -> LeftToken(),
  1488.                                this_call -> base_opt -> RightToken(),
  1489.                                this_type -> ContainingPackage() -> PackageName(),
  1490.                                this_type -> ExternalName(),
  1491.                                containing_type -> ContainingPackage() -> PackageName(),
  1492.                                containing_type -> ExternalName(),
  1493.                                expr_type -> ContainingPackage() -> PackageName(),
  1494.                                expr_type -> ExternalName());
  1495.                 this_call -> base_opt -> symbol = control.no_type;
  1496.             }
  1497.         }
  1498.     }
  1499.     else // (! super_call -> base_opt)
  1500.     {
  1501.         if (this_type -> IsInner())
  1502.             this_call -> base_opt = CreateAccessToType(this_call, containing_type);
  1503.     }
  1504.  
  1505.     bool no_bad_argument = true;
  1506.  
  1507.     for (int i = 0; i < this_call -> NumArguments(); i++)
  1508.     {
  1509.         AstExpression *expr = (AstExpression *) this_call -> Argument(i);
  1510.         ProcessExpressionOrStringConstant(expr);
  1511.         no_bad_argument = no_bad_argument && (expr -> Type() != control.no_type);
  1512.     }
  1513.     if (no_bad_argument)
  1514.     {
  1515.         MethodSymbol *constructor = FindConstructor(this_type, this_call, this_call -> LeftToken(), this_call -> RightToken());
  1516.         if (constructor)
  1517.         {
  1518.             this_call -> symbol = constructor;
  1519.  
  1520.             for (int i = 0; i < this_call -> NumArguments(); i++)
  1521.             {
  1522.                 AstExpression *expr = this_call -> Argument(i);
  1523.                 if (expr -> Type() != constructor -> FormalParameter(i) -> Type())
  1524.                     this_call -> Argument(i) = ConvertToType(expr, constructor -> FormalParameter(i) -> Type());
  1525.             }
  1526.  
  1527.             for (int k = constructor -> NumThrows() - 1; k >= 0; k--)
  1528.             {
  1529.                 TypeSymbol *exception = constructor -> Throws(k);
  1530.                 if (! CatchableException(exception))
  1531.                 {
  1532.                     ReportSemError(SemanticError::CONSTRUCTOR_DOES_NOT_THROW_THIS_EXCEPTION,
  1533.                                    this_call -> this_token,
  1534.                                    this_call -> this_token,
  1535.                                    exception -> ContainingPackage() -> PackageName(),
  1536.                                    exception -> ExternalName());
  1537.                 }
  1538.             }
  1539.  
  1540.             if (this_type -> IsLocal()) // a local type may use enclosed local variables?
  1541.                 this_type -> AddLocalConstructorCallEnvironment(GetEnvironment(this_call));
  1542.  
  1543.             //
  1544.             // Note that there is no need to do access-checking as we are allowed,
  1545.             // within the body of a class, to invoke any other constructor or member
  1546.             // (private or otherwise) in that class.
  1547.             //
  1548.         }
  1549.     }
  1550.  
  1551.     ExplicitConstructorInvocation() = NULL; // signal that we are no longer processing an explicit constructor invocation
  1552.  
  1553.     this_call -> can_complete_normally = this_call -> is_reachable; 
  1554.  
  1555.     return;
  1556. }
  1557.  
  1558.  
  1559. void Semantic::ProcessSuperCall(AstSuperCall *super_call)
  1560. {
  1561.     TypeSymbol *this_type = ThisType();
  1562.     ExplicitConstructorInvocation() = super_call; // signal that we are about to process an explicit constructor invocation
  1563.  
  1564.     TypeSymbol *super_type = this_type -> super;
  1565.     if (! super_type) // this is only possible if we are compiling an illegal Object.java source file.
  1566.         super_type = control.Object();
  1567.  
  1568.     if (super_call -> base_opt)
  1569.     {
  1570.         if (! control.option.one_one)
  1571.         {
  1572.             ReportSemError(SemanticError::ONE_ONE_FEATURE,
  1573.                            super_call -> base_opt -> LeftToken(),
  1574.                            super_call -> dot_token_opt);
  1575.         }
  1576.  
  1577.         ProcessExpression(super_call -> base_opt);
  1578.  
  1579.         TypeSymbol *expr_type = super_call -> base_opt -> Type();
  1580.         if (expr_type != control.no_type)
  1581.         {
  1582.             TypeSymbol *containing_type = super_type -> ContainingType();
  1583.             if (! containing_type)
  1584.             {
  1585.                 ReportSemError(SemanticError::SUPER_TYPE_NOT_INNER_CLASS,
  1586.                                super_call -> base_opt -> LeftToken(),
  1587.                                super_call -> base_opt -> RightToken(),
  1588.                                super_type -> ContainingPackage() -> PackageName(),
  1589.                                super_type -> ExternalName(),
  1590.                                this_type -> ContainingPackage() -> PackageName(),
  1591.                                this_type -> ExternalName(),
  1592.                                expr_type -> ContainingPackage() -> PackageName(),
  1593.                                expr_type -> ExternalName());
  1594.                 super_call -> base_opt -> symbol = control.no_type;
  1595.             }
  1596.             //
  1597.             // 1.2 change. In 1.1, we used to allow access to any subclass of type. Now, there must
  1598.             // be a perfect match.
  1599.             //
  1600.             // else if (! expr_type -> IsSubclass(containing_type))
  1601.             //
  1602.             else if (expr_type != containing_type)
  1603.             {
  1604.                 ReportSemError(SemanticError::INVALID_ENCLOSING_INSTANCE,
  1605.                                super_call -> base_opt -> LeftToken(),
  1606.                                super_call -> base_opt -> RightToken(),
  1607.                                this_type -> ContainingPackage() -> PackageName(),
  1608.                                this_type -> ExternalName(),
  1609.                                containing_type -> ContainingPackage() -> PackageName(),
  1610.                                containing_type -> ExternalName(),
  1611.                                expr_type -> ContainingPackage() -> PackageName(),
  1612.                                expr_type -> ExternalName());
  1613.                 super_call -> base_opt -> symbol = control.no_type;
  1614.             }
  1615.         }
  1616.     }
  1617.     else // (! super_call -> base_opt)
  1618.     {
  1619.         if (super_type && super_type -> IsInner())
  1620.             super_call -> base_opt = CreateAccessToType(super_call, super_type -> ContainingType());
  1621.     }
  1622.  
  1623.     bool no_bad_argument = true;
  1624.     for (int i = 0; i < super_call -> NumArguments(); i++)
  1625.     {
  1626.         AstExpression *expr = (AstExpression *) super_call -> Argument(i);
  1627.         ProcessExpressionOrStringConstant(expr);
  1628.         no_bad_argument = no_bad_argument && (expr -> Type() != control.no_type);
  1629.     }
  1630.  
  1631.     if (this_type == control.Object())
  1632.     {
  1633.         super_call -> symbol = NULL;
  1634.         ReportSemError(SemanticError::MISPLACED_SUPER_EXPRESSION,
  1635.                        super_call -> super_token,
  1636.                        super_call -> super_token);
  1637.     }
  1638.     else if (no_bad_argument)
  1639.     {
  1640.         MethodSymbol *constructor = FindConstructor(super_type, super_call, super_call -> LeftToken(), super_call -> RightToken());
  1641.  
  1642.         if (constructor)
  1643.         {
  1644.             //
  1645.             // No need to do a full access-check. Do the minimal stuff here !
  1646.             //
  1647.             if (constructor -> ACC_PRIVATE())
  1648.             {
  1649.                 if (this_type -> outermost_type == super_type -> outermost_type)
  1650.                 {
  1651.                      //
  1652.                      // TODO: Awaiting language clarification.
  1653.                      //
  1654.                      ReportSemError(SemanticError::PRIVATE_ENCLOSED_CONSTRUCTOR,
  1655.                                     super_call -> LeftToken(),
  1656.                                     super_call -> RightToken(),
  1657.                                     constructor -> Header());
  1658.  
  1659.                      constructor = TypeSymbol::GetReadAccessMethod(constructor);
  1660.                 }
  1661.                 else ReportSemError(SemanticError::PRIVATE_CONSTRUCTOR_NOT_ACCESSIBLE,
  1662.                                     super_call -> LeftToken(),
  1663.                                     super_call -> RightToken(),
  1664.                                     constructor -> Header(),
  1665.                                     super_type -> ContainingPackage() -> PackageName(),
  1666.                                     super_type -> ExternalName());
  1667.             }
  1668.             else if (! (constructor -> ACC_PUBLIC() || constructor -> ACC_PROTECTED()))
  1669.             {
  1670.                 if (! (this_type -> outermost_type == super_type -> outermost_type ||
  1671.                        super_type -> ContainingPackage() == this_package))
  1672.                     ReportSemError(SemanticError::DEFAULT_CONSTRUCTOR_NOT_ACCESSIBLE,
  1673.                                    super_call -> super_token,
  1674.                                    super_call -> super_token,
  1675.                                    constructor -> Header(),
  1676.                                    super_type -> ContainingPackage() -> PackageName(),
  1677.                                    super_type -> ExternalName());
  1678.             }
  1679.  
  1680.             super_call -> symbol = constructor;
  1681.  
  1682.             if (super_call -> base_opt &&
  1683.                 (super_call -> base_opt -> Type() != control.no_type) &&
  1684.                 (super_call -> base_opt -> Type() != super_type -> ContainingType()))
  1685.             {
  1686. assert(CanMethodInvocationConvert(super_type -> ContainingType(), super_call -> base_opt -> Type()));
  1687.                 super_call -> base_opt = ConvertToType(super_call -> base_opt, super_type -> ContainingType());
  1688.             }
  1689.  
  1690.             for (int i = 0; i < super_call -> NumArguments(); i++)
  1691.             {
  1692.                 AstExpression *expr = super_call -> Argument(i);
  1693.                 if (expr -> Type() != constructor -> FormalParameter(i) -> Type())
  1694.                     super_call -> Argument(i) = ConvertToType(expr, constructor -> FormalParameter(i) -> Type());
  1695.             }
  1696.  
  1697.             for (int k = constructor -> NumThrows((Semantic *) this, super_call -> super_token) - 1; k >= 0; k--)
  1698.             {
  1699.                 TypeSymbol *exception = constructor -> Throws(k);
  1700.                 if (! CatchableException(exception))
  1701.                 {
  1702.                     ReportSemError(SemanticError::CONSTRUCTOR_DOES_NOT_THROW_SUPER_EXCEPTION,
  1703.                                    super_call -> LeftToken(),
  1704.                                    super_call -> RightToken(),
  1705.                                    this_type -> Name(),
  1706.                                    exception -> ContainingPackage() -> PackageName(),
  1707.                                    exception -> ExternalName(),
  1708.                                    constructor -> containing_type -> ContainingPackage() -> PackageName(),
  1709.                                    constructor -> containing_type -> ExternalName());
  1710.                 }
  1711.             }
  1712.  
  1713.             if (super_type -> IsLocal()) // a local type may use enclosed local variables?
  1714.             {
  1715.                 if (super_type -> LocalClassProcessingCompleted())
  1716.                 {
  1717.                     for (int i = 1; i < super_type -> NumConstructorParameters(); i++)
  1718.                     {
  1719.                         VariableSymbol *local = super_type -> ConstructorParameter(i) -> accessed_local;
  1720.  
  1721.                         AstSimpleName *simple_name = compilation_unit -> ast_pool -> GenSimpleName(super_call -> super_token);
  1722.  
  1723.                         this_type -> FindOrInsertLocalShadow(local);
  1724. assert(ThisMethod() -> LocalConstructor() && (! ThisMethod() -> IsGeneratedLocalConstructor()));
  1725.                         BlockSymbol *block_symbol = ThisMethod() -> LocalConstructor() -> block_symbol;
  1726.                         simple_name -> symbol = block_symbol -> FindVariableSymbol(local -> Identity());
  1727. assert(simple_name -> symbol); // for the time being, we will now process sources with the error below...
  1728.                         //
  1729.                         // This is possible if the source contains a method that erroneously calls a super class.
  1730.                         //
  1731.                         if (! simple_name -> symbol)
  1732.                             simple_name -> symbol = control.no_type;
  1733.                         super_call -> AddLocalArgument(simple_name);
  1734.                     }
  1735. assert(constructor -> LocalConstructor() && (! constructor -> IsGeneratedLocalConstructor()));
  1736.                     super_call -> symbol = constructor -> LocalConstructor();
  1737.                 }
  1738.                 else // are we currently within the body of the type in question ?
  1739.                 {
  1740.                     super_type -> AddLocalConstructorCallEnvironment(GetEnvironment(super_call));
  1741.                 }
  1742.             }
  1743.         }
  1744.     }
  1745.  
  1746.     ExplicitConstructorInvocation() = NULL; // signal that we are no longer processing an explicit constructor invocation
  1747.  
  1748.     super_call -> can_complete_normally = super_call -> is_reachable; 
  1749.  
  1750.     return;
  1751. }
  1752.  
  1753.  
  1754. void Semantic::CheckThrow(AstExpression *throw_expression)
  1755. {
  1756.     TypeSymbol *throw_type = throw_expression -> symbol -> TypeCast();
  1757. assert(throw_type);
  1758.  
  1759.     if (throw_type -> ACC_INTERFACE())
  1760.     {
  1761.         ReportSemError(SemanticError::NOT_A_CLASS,
  1762.                        throw_expression -> LeftToken(),
  1763.                        throw_expression -> RightToken(),
  1764.                        throw_type -> ContainingPackage() -> PackageName(),
  1765.                        throw_type -> ExternalName());
  1766.     }
  1767.     else if (! throw_type -> IsSubclass(control.Throwable()))
  1768.     {
  1769.         ReportSemError(SemanticError::TYPE_NOT_THROWABLE,
  1770.                        throw_expression -> LeftToken(),
  1771.                        throw_expression -> RightToken(),
  1772.                        throw_type -> ContainingPackage() -> PackageName(),
  1773.                        throw_type -> ExternalName());
  1774.     }
  1775.  
  1776.     return;
  1777. }
  1778.  
  1779.  
  1780. void Semantic::ProcessMethodBody(AstMethodDeclaration *method_declaration)
  1781. {
  1782.     MethodSymbol *this_method = ThisMethod();
  1783.  
  1784.     for (int k = 0; k < method_declaration -> NumThrows(); k++)
  1785.         CheckThrow(method_declaration -> Throw(k));
  1786.  
  1787.     AstMethodDeclarator *method_declarator = method_declaration -> method_declarator;
  1788.  
  1789.     if (! method_declaration -> method_body -> EmptyStatementCast())
  1790.     {
  1791.         //
  1792.         // The block that is the body of a method is reachable
  1793.         //
  1794.         AstBlock *block_body;
  1795.  
  1796.         //
  1797.         // The body of a method must be a regular block. If instead, it
  1798.         // is a constructor block, mark the compilation unit as a bad
  1799.         // compilation so that the parser can properly diagnose this
  1800.         // problem later.
  1801.         //
  1802.         AstConstructorBlock *constructor_block = method_declaration -> method_body -> ConstructorBlockCast();
  1803.         if (constructor_block)
  1804.         {
  1805.             compilation_unit -> kind = Ast::BAD_COMPILATION; // invalidate the compilation unit
  1806.  
  1807.             constructor_block -> is_reachable = true;
  1808.             block_body = constructor_block -> block;
  1809.  
  1810.             //
  1811.             // If the parser recognizes the body of a method as a ConstructorBlock
  1812.             // then it must have an explicit_constructor_invocation.
  1813.             //
  1814.             AstThisCall *this_call = constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast();
  1815.             if (this_call)
  1816.             {
  1817.                 this_call -> is_reachable = true;
  1818.                 //
  1819.                 // Do not process the explicit constructor invocation as this could
  1820.                 // cause problems with assertions (e.g. for inner classes) that will
  1821.                 // turn out not to be true.
  1822.                 //
  1823.                 // ProcessThisCall(this_call);
  1824.                 //
  1825.                 block_body -> is_reachable = this_call -> can_complete_normally;
  1826.             }
  1827.             else
  1828.             {
  1829.                 AstSuperCall *super_call = (AstSuperCall *) constructor_block -> explicit_constructor_invocation_opt;
  1830.                 super_call -> is_reachable = true;
  1831.                 //
  1832.                 // Do not process the explicit constructor invocation as this could
  1833.                 // cause problems with assertions (e.g. for inner classes) that will
  1834.                 // turn out not to be true.
  1835.                 //
  1836.                 // ProcessSuperCall(super_call);
  1837.                 //
  1838.                 block_body -> is_reachable = super_call -> can_complete_normally;
  1839.             }
  1840.         }
  1841.         else
  1842.         {
  1843.             block_body = (AstBlock *) method_declaration -> method_body;
  1844.             block_body -> is_reachable = true;
  1845.         }
  1846.  
  1847.         block_body -> block_symbol = this_method -> block_symbol;
  1848.         block_body -> nesting_level = LocalBlockStack().Size();
  1849.         LocalBlockStack().Push(block_body);
  1850.  
  1851.         ProcessBlockStatements(block_body); 
  1852.  
  1853.         LocalBlockStack().Pop();
  1854.  
  1855.         if (block_body -> can_complete_normally)
  1856.         {
  1857.             if (this_method -> Type() == control.void_type)
  1858.             {
  1859.                 AstReturnStatement *return_statement = compilation_unit -> ast_pool -> GenReturnStatement();
  1860.                 return_statement -> return_token = block_body -> right_brace_token;
  1861.                 return_statement -> expression_opt = NULL;
  1862.                 return_statement -> semicolon_token = block_body -> right_brace_token;
  1863.                 return_statement -> is_reachable = true;
  1864.                 block_body -> can_complete_normally = false;
  1865.                 block_body -> AddStatement(return_statement);
  1866.             }
  1867.             else
  1868.             {
  1869.                 ReportSemError(SemanticError::TYPED_METHOD_WITH_NO_RETURN,
  1870.                                method_declaration -> type -> LeftToken(),
  1871.                                method_declaration -> method_declarator -> identifier_token,
  1872.                                this_method -> Header(),
  1873.                                this_method -> Type() -> Name());
  1874.             }
  1875.         }
  1876.  
  1877.         if (this_method -> ACC_ABSTRACT() || this_method -> ACC_NATIVE())
  1878.         {
  1879.             ReportSemError(SemanticError::ABSTRACT_METHOD_WITH_BODY,
  1880.                            method_declaration -> LeftToken(),
  1881.                            method_declaration -> RightToken(),
  1882.                            this_method -> Header());
  1883.         }
  1884.     }
  1885.     else if (! (this_method -> ACC_ABSTRACT() || this_method -> ACC_NATIVE()))
  1886.     {
  1887.         ReportSemError(SemanticError::NON_ABSTRACT_METHOD_WITHOUT_BODY,
  1888.                        method_declaration -> LeftToken(),
  1889.                        method_declaration -> RightToken(),
  1890.                        this_method -> Header());
  1891.     }
  1892.  
  1893.     this_method -> block_symbol -> CompressSpace(); // space optimization
  1894.  
  1895.     return;
  1896. }
  1897.  
  1898.  
  1899. void Semantic::ProcessConstructorBody(AstConstructorDeclaration *constructor_declaration, bool body_reachable)
  1900. {
  1901.     TypeSymbol *this_type = ThisType();
  1902.     MethodSymbol *this_method = ThisMethod();
  1903.  
  1904.     for (int k = 0; k < constructor_declaration -> NumThrows(); k++)
  1905.         CheckThrow(constructor_declaration -> Throw(k));
  1906.  
  1907.     AstMethodDeclarator *constructor_declarator = constructor_declaration -> constructor_declarator;
  1908.  
  1909.     //
  1910.     // The block that is the body of a constructor is reachable
  1911.     //
  1912.     AstConstructorBlock *constructor_block = constructor_declaration -> constructor_body;
  1913.  
  1914.     constructor_block -> is_reachable = true;
  1915.     AstBlock *block_body = constructor_block -> block;
  1916.     AstThisCall *this_call = NULL;
  1917.     AstSuperCall *super_call = NULL;
  1918.     TypeSymbol *super_type = this_type -> super;
  1919.  
  1920.     if (constructor_block -> explicit_constructor_invocation_opt)
  1921.     {
  1922.         this_call = constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast();
  1923.         super_call = constructor_block -> explicit_constructor_invocation_opt -> SuperCallCast();
  1924.     }
  1925.     else if (super_type)
  1926.     {
  1927.         LexStream::TokenIndex loc = block_body -> LeftToken();
  1928.         super_call                            = compilation_unit -> ast_pool -> GenSuperCall();
  1929.         super_call -> base_opt                = NULL;
  1930.         super_call -> dot_token_opt           = loc;
  1931.         super_call -> super_token             = loc;
  1932.         super_call -> left_parenthesis_token  = loc;
  1933.         super_call -> right_parenthesis_token = loc;
  1934.         super_call -> semicolon_token         = loc;
  1935.  
  1936.         constructor_block -> explicit_constructor_invocation_opt = super_call;
  1937.  
  1938.         if (super_type -> IsInner() && (! this_type -> CanAccess(super_type -> ContainingType())))
  1939.         {
  1940.             ReportSemError(SemanticError::ENCLOSING_INSTANCE_NOT_ACCESSIBLE,
  1941.                            constructor_declaration -> constructor_declarator -> LeftToken(),
  1942.                            constructor_declaration -> constructor_declarator -> RightToken(),
  1943.                            super_type -> ContainingType() -> ContainingPackage() -> PackageName(),
  1944.                            super_type -> ContainingType() -> ExternalName());
  1945.         }
  1946.     }
  1947.  
  1948.     //
  1949.     // If the constructor starts with an explicit_constructor_invocation, either
  1950.     // one specified by the user or generated, we process it and set up the proper
  1951.     // local environment, if appropriate...
  1952.     //
  1953.     if (constructor_block -> explicit_constructor_invocation_opt)
  1954.     {
  1955.         //
  1956.         // If we are processing a local constructor, set up the generated environment...
  1957.         //
  1958.         if (this_type -> IsLocal())
  1959.         {
  1960.             LocalSymbolTable().Pop();
  1961. assert(this_method -> LocalConstructor() && (! this_method -> IsGeneratedLocalConstructor()));
  1962.             LocalSymbolTable().Push(this_method -> LocalConstructor() -> block_symbol -> Table());
  1963.         }
  1964.  
  1965.             if (this_call)
  1966.             {
  1967.                 this_call -> is_reachable = true;
  1968.                 ProcessThisCall(this_call);
  1969.             }
  1970.             else
  1971.             {
  1972. assert(super_call);
  1973.                 super_call -> is_reachable = true;
  1974.                 ProcessSuperCall(super_call);
  1975.             }
  1976.  
  1977.         //
  1978.         // If we are processing a local constructor, restore its original environment...
  1979.         //
  1980.         if (this_type -> IsLocal())
  1981.         {
  1982.             LocalSymbolTable().Pop();
  1983.             LocalSymbolTable().Push(this_method -> block_symbol -> Table());
  1984.         }
  1985.     }
  1986.  
  1987.     if (! (body_reachable || (constructor_block -> explicit_constructor_invocation_opt &&
  1988.                               constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast())))
  1989.     {
  1990.         ReportSemError(SemanticError::UNREACHABLE_CONSTRUCTOR_BODY,
  1991.                        constructor_declaration -> LeftToken(),
  1992.                        constructor_declaration -> RightToken());
  1993.     }
  1994.  
  1995.     //
  1996.     // Guess that the number of elements will not exceed the number of statements.
  1997.     //
  1998.     int table_size = block_body -> NumStatements();
  1999.     BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol(table_size);
  2000.     //
  2001.     // enclosing_block is not present only when we are processing the block of a static initializer
  2002.     //
  2003.     block -> max_variable_index = this_method -> block_symbol -> max_variable_index;
  2004.     LocalSymbolTable().Push(block -> Table());
  2005.  
  2006.     block_body -> is_reachable = true;
  2007.     block_body -> block_symbol = block;
  2008.     block_body -> nesting_level = LocalBlockStack().Size();
  2009.     LocalBlockStack().Push(block_body);
  2010.  
  2011.     ProcessBlockStatements(block_body); 
  2012.  
  2013.     if (block_body -> can_complete_normally)
  2014.     {
  2015.         AstReturnStatement *return_statement = compilation_unit -> ast_pool -> GenReturnStatement();
  2016.         return_statement -> return_token = block_body -> right_brace_token;
  2017.         return_statement -> expression_opt = NULL;
  2018.         return_statement -> semicolon_token = block_body -> right_brace_token;
  2019.         return_statement -> is_reachable = true;
  2020.         block_body -> can_complete_normally = false;
  2021.         block_body -> AddStatement(return_statement);
  2022.     }
  2023.  
  2024.     constructor_block -> can_complete_normally = block_body -> can_complete_normally;
  2025.  
  2026.     LocalBlockStack().Pop();
  2027.     LocalSymbolTable().Pop();
  2028.  
  2029.     block -> CompressSpace(); // space optimization
  2030.  
  2031.     return;
  2032. }
  2033.  
  2034.  
  2035. void Semantic::ProcessExecutableBodies(SemanticEnvironment *environment, AstClassBody *class_body)
  2036. {
  2037.     state_stack.Push(environment);
  2038.     TypeSymbol *this_type = ThisType();
  2039.  
  2040. assert(this_type -> HeaderProcessed());
  2041. assert(this_type -> ConstructorMembersProcessed());
  2042. assert(this_type -> MethodMembersProcessed());
  2043. assert(this_type -> FieldMembersProcessed());
  2044.  
  2045.     ThisVariable() = NULL; // All variable declarations have already been processed
  2046.  
  2047.     //
  2048.     // Compute the set of instance final variables declared by the user in this type
  2049.     // as well as the set of instance final variables that have not yet been initialized.
  2050.     //
  2051.     Tuple<VariableSymbol *> finals(this_type -> NumVariableSymbols()),
  2052.                             unassigned_finals(this_type -> NumVariableSymbols());
  2053.     for (int k = 0; k < this_type -> NumVariableSymbols(); k++)
  2054.     {
  2055.         VariableSymbol *variable_symbol = this_type -> VariableSym(k);
  2056.         if (variable_symbol -> ACC_FINAL() && variable_symbol -> declarator)
  2057.         {
  2058.             finals.Next() = variable_symbol;
  2059.  
  2060.             if (! variable_symbol -> IsDefinitelyAssigned())
  2061.                 unassigned_finals.Next() = variable_symbol;
  2062.         }
  2063.     }
  2064.  
  2065.     AstBlock *last_block_body = (class_body -> NumBlocks() > 0 ? class_body -> Block(class_body -> NumBlocks() - 1)
  2066.                                                                : (AstBlock *) NULL);
  2067.     if (class_body -> NumConstructors() == 0)
  2068.     {
  2069.         //
  2070.         // Issue an error for each unassigned final.
  2071.         //
  2072.         for (int k = 0; k < unassigned_finals.Length(); k++)
  2073.         {
  2074.             ReportSemError(SemanticError::UNINITIALIZED_FINAL_VARIABLE,
  2075.                            unassigned_finals[k] -> declarator -> LeftToken(),
  2076.                            unassigned_finals[k] -> declarator -> RightToken());
  2077.         }
  2078.  
  2079.         //
  2080.         // Process the body of the default constructor, if there is one.
  2081.         // (An anonymous class does not yet have a default constructor at this point.)
  2082.         //
  2083.         AstConstructorDeclaration *constructor_decl = class_body -> default_constructor;
  2084.         if (constructor_decl)
  2085.         {
  2086.             ThisMethod() = constructor_decl -> constructor_symbol;
  2087.  
  2088.             LocalSymbolTable().Push(ThisMethod() -> block_symbol -> Table());
  2089.             LocalBlockStack().max_size = 0;
  2090.             ProcessConstructorBody(constructor_decl, ((! last_block_body) || last_block_body -> can_complete_normally));
  2091.             LocalSymbolTable().Pop();
  2092.             ThisMethod() -> max_block_depth = LocalBlockStack().max_size;
  2093.         }
  2094.     }
  2095.     else 
  2096.     {
  2097.         for (int i = 0; i < class_body -> NumConstructors(); i++)
  2098.         {
  2099.             AstConstructorDeclaration *constructor_decl = class_body -> Constructor(i);
  2100.  
  2101.             ThisMethod() = constructor_decl -> constructor_symbol;
  2102.             MethodSymbol *this_method = ThisMethod();
  2103.             if (this_method)
  2104.             {
  2105.                 for (int l = 0; l < this_method -> NumFormalParameters(); l++)
  2106.                 {
  2107.                     VariableSymbol *parm = this_method -> FormalParameter(l);
  2108.                     AstVariableDeclaratorId *name = (AstVariableDeclaratorId *) parm -> declarator;
  2109.  
  2110.                     SemanticEnvironment *where_found;
  2111.                     Tuple<VariableSymbol *> variables_found(2);
  2112.                     SearchForVariableInEnvironment(variables_found, where_found, state_stack.Top(),
  2113.                                                    parm -> Identity(),
  2114.                                                    name -> identifier_token);
  2115.                     VariableSymbol *symbol = (variables_found.Length() > 0 ? variables_found[0] : (VariableSymbol *) NULL);
  2116.                     if (symbol && symbol -> IsLocal())
  2117.                     {
  2118.                         ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  2119.                                        name -> identifier_token,
  2120.                                        name -> identifier_token,
  2121.                                        parm -> Name());
  2122.                     }
  2123.                 }
  2124.  
  2125.                 AstConstructorBlock *constructor_block = constructor_decl -> constructor_body;
  2126.                 if (constructor_block -> explicit_constructor_invocation_opt &&
  2127.                     constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast())
  2128.                 {
  2129.                     for (int j = 0; j < unassigned_finals.Length(); j++)
  2130.                         unassigned_finals[j] -> MarkDefinitelyAssigned();
  2131.                 }
  2132.                 else
  2133.                 {
  2134.                     for (int j = 0; j < unassigned_finals.Length(); j++)
  2135.                         unassigned_finals[j] -> MarkNotDefinitelyAssigned();
  2136.                 }
  2137.  
  2138.                 LocalSymbolTable().Push(this_method -> block_symbol -> Table());
  2139.                 LocalBlockStack().max_size = 0;
  2140.  
  2141.                 int start_num_errors = NumErrors();
  2142.                 ProcessConstructorBody(constructor_decl, ((! last_block_body) || last_block_body -> can_complete_normally));
  2143.  
  2144.                 LocalSymbolTable().Pop();
  2145.                 this_method -> max_block_depth = LocalBlockStack().max_size;
  2146.  
  2147.                 if (NumErrors() == start_num_errors)
  2148.                     DefiniteConstructorBody(constructor_decl, finals);
  2149.  
  2150.                 for (int k = 0; k < unassigned_finals.Length(); k++)
  2151.                 {
  2152.                     VariableSymbol *variable_symbol = unassigned_finals[k];
  2153.                     if (! variable_symbol -> IsDefinitelyAssigned())
  2154.                     {
  2155.                         ReportSemError(SemanticError::UNINITIALIZED_FINAL_VARIABLE_IN_CONSTRUCTOR,
  2156.                                        constructor_decl -> LeftToken(),
  2157.                                        constructor_decl -> RightToken(),
  2158.                                        variable_symbol -> Name());
  2159.                     }
  2160.                 }
  2161.             }
  2162.         }
  2163.  
  2164.         for (int l = 0; l < this_type -> NumPrivateAccessConstructors(); l++)
  2165.         {
  2166.             ThisMethod() = this_type -> PrivateAccessConstructor(l);
  2167.             MethodSymbol *this_method = ThisMethod();
  2168.             AstConstructorDeclaration *constructor_decl = (AstConstructorDeclaration *)
  2169.                                                           this_method -> method_or_constructor_declaration;
  2170.  
  2171.             LocalSymbolTable().Push(this_method -> block_symbol -> Table());
  2172.             LocalBlockStack().max_size = 0;
  2173.             ProcessConstructorBody(constructor_decl, true);
  2174.             LocalSymbolTable().Pop();
  2175.             this_method -> max_block_depth = LocalBlockStack().max_size;
  2176.         }
  2177.  
  2178.         ConstructorCycleChecker cycle_checker(class_body);
  2179.     }
  2180.  
  2181.     for (int j = 0; j < class_body -> NumMethods(); j++)
  2182.     {
  2183.         AstMethodDeclaration *method_decl = class_body -> Method(j);
  2184.  
  2185.         ThisMethod() = method_decl -> method_symbol;
  2186.         MethodSymbol *this_method = ThisMethod();
  2187.         if (this_method)
  2188.         {
  2189.             //
  2190.             // TODO: Confirm that this new test is indeed necessary. In 1.0, a more restricted test was used...
  2191.             //
  2192.             for (int i = 0; i < this_method -> NumFormalParameters(); i++)
  2193.             {
  2194.                 VariableSymbol *parm = this_method -> FormalParameter(i);
  2195.                 AstVariableDeclaratorId *name = (AstVariableDeclaratorId *) parm -> declarator;
  2196.  
  2197.                 SemanticEnvironment *where_found;
  2198.                 Tuple<VariableSymbol *> variables_found(2);
  2199.                 SearchForVariableInEnvironment(variables_found, where_found, state_stack.Top(),
  2200.                                                parm -> Identity(),
  2201.                                                name -> identifier_token);
  2202.                 VariableSymbol *symbol = (variables_found.Length() > 0 ? variables_found[0] : (VariableSymbol *) NULL);
  2203.                 if (symbol && symbol -> IsLocal())
  2204.                 {
  2205.                     ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  2206.                                    name -> identifier_token,
  2207.                                    name -> identifier_token,
  2208.                                    parm -> Name());
  2209.                 }
  2210.             }
  2211.  
  2212.             LocalSymbolTable().Push(this_method -> block_symbol -> Table());
  2213.             LocalBlockStack().max_size = 0;
  2214.  
  2215.             int start_num_errors = NumErrors();
  2216.             ProcessMethodBody(method_decl);
  2217.  
  2218.             LocalSymbolTable().Pop();
  2219.             this_method -> max_block_depth = LocalBlockStack().max_size;
  2220.  
  2221.             if (NumErrors() == start_num_errors)
  2222.                 DefiniteMethodBody(method_decl, finals);
  2223.         }
  2224.     }
  2225.  
  2226.     //
  2227.     // Mark all instance variables and constructor parameters final.
  2228.     //
  2229.     for (int i = 0; i <  this_type -> NumConstructorParameters(); i++)
  2230.         this_type -> ConstructorParameter(i) -> SetACC_FINAL();
  2231.  
  2232.     for (int l = 0; l <  this_type -> NumEnclosingInstances(); l++)
  2233.         this_type -> EnclosingInstance(l) -> SetACC_FINAL();
  2234.  
  2235.     //
  2236.     // We are done with all the methods, indicate that there is no method
  2237.     // being currently compiled in this environment.
  2238.     //
  2239.     ThisMethod() = NULL;
  2240.  
  2241.     //
  2242.     // Recursively process all inner types
  2243.     //
  2244.     for (int m = 0; m < class_body -> NumNestedClasses(); m++)
  2245.     {
  2246.         AstClassDeclaration *class_declaration = class_body -> NestedClass(m);
  2247.         if (class_declaration -> semantic_environment)
  2248.             ProcessExecutableBodies(class_declaration -> semantic_environment, class_declaration -> class_body);
  2249.     }
  2250.  
  2251.     for (int n = 0; n < class_body -> NumNestedInterfaces(); n++)
  2252.     {
  2253.         if (class_body -> NestedInterface(n) -> semantic_environment)
  2254.             ProcessExecutableBodies(class_body -> NestedInterface(n));
  2255.     }
  2256.  
  2257.     state_stack.Pop();
  2258.  
  2259.     return;
  2260. }
  2261.  
  2262.  
  2263. void Semantic::ProcessExecutableBodies(AstInterfaceDeclaration *interface_declaration)
  2264. {
  2265.     state_stack.Push(interface_declaration -> semantic_environment);
  2266.     TypeSymbol *this_type = ThisType();
  2267. assert(this_type -> HeaderProcessed());
  2268. assert(this_type -> MethodMembersProcessed());
  2269. assert(this_type -> FieldMembersProcessed());
  2270.  
  2271.     for (int k = 0; k < this_type -> NumVariableSymbols(); k++)
  2272.     {
  2273.         VariableSymbol *variable_symbol = this_type -> VariableSym(k);
  2274.         if (! variable_symbol -> IsDefinitelyAssigned())
  2275.         {
  2276.             ReportSemError(SemanticError::UNINITIALIZED_FINAL_VARIABLE,
  2277.                            variable_symbol -> declarator -> LeftToken(),
  2278.                            variable_symbol -> declarator -> RightToken());
  2279.         }
  2280.     }
  2281.  
  2282.     //
  2283.     // Recursively process all inner types
  2284.     //
  2285.     for (int m = 0; m < interface_declaration -> NumNestedClasses(); m++)
  2286.     {
  2287.         AstClassDeclaration *class_declaration = interface_declaration -> NestedClass(m);
  2288.         if (class_declaration -> semantic_environment)
  2289.             ProcessExecutableBodies(class_declaration -> semantic_environment, class_declaration -> class_body);
  2290.     }
  2291.  
  2292.     for (int n = 0; n < interface_declaration -> NumNestedInterfaces(); n++)
  2293.     {
  2294.         if (interface_declaration -> NestedInterface(n) -> semantic_environment)
  2295.             ProcessExecutableBodies(interface_declaration -> NestedInterface(n));
  2296.     }
  2297.  
  2298.     state_stack.Pop();
  2299.  
  2300.     return;
  2301. }
  2302.